/*
 * ImageManager.java
 *
 * Created on 2 June 2003, 13:13
 *
 * Copyright 2009 the Desert Labs Project (http://desertlabs.us)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package us.desertlabs.visuals;

import java.awt.Component;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Logger;

/**
 * This is a simple utility to assist in the quick use of {@link Image}
 * objects. Each instance of {@link ImageManager} maintains a cache of
 * loaded images that is populated as the images are requested with the {@link #getImage}
 * method.
 *
 * @author Brandon Franklin
 */
public class ImageManager {

    /** The singleton instance of {@link ImageManager} */
    static private ImageManager INSTANCE;

    /**
     * Returns the singleton instance of {@link ImageManager}.
     *
     * @return the {@link ImageManager} singleton
     */
    static synchronized public ImageManager getInstance() {

        if (INSTANCE == null) {
            INSTANCE = new ImageManager();
        }

        return INSTANCE;
    }

    /** A name-to-{@link Image} record of all loaded images */
    private final Map<String, Image> cache;

    /** A {@link MediaTracker} used to track the loading of images */
    private final MediaTracker tracker;

    /**
     * Creates a new instance of {@link ImageManager} and prepares it for
     * use.
     */
    @SuppressWarnings("serial")
    private ImageManager() {
        cache = new HashMap<String, Image>();
        tracker = new MediaTracker( new Component() {} );
    }

    /**
     * Retrieves and returns the {@link Image} with the supplied name.
     * This will involve either loading the image from an external resource or
     * returning it directly from the {@link ImageManager}'s cache.
     *
     * @param name the name of the image to retrieve
     * @return the {@link Image} requested
     */
    public synchronized Image getImage(final String name) {

        Image img;

        // First check the cache
        if (cache.containsKey(name)) {
            img = cache.get(name);

        }
        else { // Not in the cache, so try loading it

            final URL imgLoc = Thread.currentThread().getContextClassLoader().getResource(name);
            img = Toolkit.getDefaultToolkit().createImage(imgLoc);

            if (img != null) {

                tracker.addImage(img,0);
                try {
                    tracker.waitForID(0, 0);
                } catch (final InterruptedException e) {
                    // Error handling below
                }

                final int status = tracker.statusID(0, false);
                tracker.removeImage(img, 0);

                if( status == MediaTracker.COMPLETE ) {
                    // Store the image in the cache
                    cache.put(name, img);

                } else {
                    Logger.getLogger( getClass().getName() ).severe("Loading of image failed for: "+name);
                }

            } else {
                Logger.getLogger( getClass().getName() ).severe("Creation of image failed for: "+name);
            }
        }

        return img;
    }

}
